Where to go from here?
There are many ways to improve the compiler for this version of our source language. Some improvements we have identified already, in our previous compilers; some are specific to this compiler.
Below are some ideas for improvements. If you have some time and are interested, consider implementing one or more of them. You can also suggest your own!
User interface
We could implement better error messages from the parser.
We could also provide more logging / debugging output from the various phases.
Compiler features
We could implement another backend, which would emit x86 Intel syntax.
Language features
We will add more language features to the next version of the compiler. But for now, consider: What would we need to change, to allow a program to consist of multiple print statements?
Implementation
We could add a lowering stage to the compiler. Lowering takes as input an intermediate representation of a high-level language (e.g., an AST) and produces an intermediate representation for a lower-level language (e.g., a list of x86 instructions). To implement this lowering phase, we design and implement a data structure for x86 instructions. The lowering phase then walks the AST and produces a list of instances of this structure.
We could also use advanced features of Alex to tokenize string literals.
Performance
The algorithm for emitting arithmetic expressions is straightforward, but not as efficient as it could be. For one, the algorithm as written could make more efficient use of the stack. Additionally, there is a well-known algorithm that we could implement, which minimizes register use for machine code that computes arithmetic expressions.